home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gsview10.zip / doc2rtf.c < prev    next >
C/C++ Source or Header  |  1993-03-27  |  9KB  |  429 lines

  1. /*
  2.  * doc2rtf.c  -- program to convert Gnuplot .DOC format to MS windows
  3.  * help (.rtf) format.
  4.  *
  5.  * This involves stripping all lines with a leading digit or
  6.  * a leading @, #, or %.
  7.  * Modified by Maurice Castro from doc2gih.c by Thomas Williams 
  8.  *
  9.  * usage:  doc2rtf file.doc file.rtf [-d]
  10.  *
  11.  */
  12.  
  13. /* note that tables must begin in at least the second column to */
  14. /* be formatted correctly and tabs are forbidden */
  15.  
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20.  
  21. #define MAX_LINE_LEN    1024
  22. #define TRUE 1
  23. #define FALSE 0
  24.  
  25. struct LIST
  26. {
  27.     int level;
  28.     int line;
  29.     char *string;
  30.     struct LIST *next;
  31.     };
  32.  
  33. struct LIST *list = NULL;
  34. struct LIST *head = NULL;
  35.  
  36. struct LIST *keylist = NULL;
  37. struct LIST *keyhead = NULL;
  38.  
  39. int debug = FALSE;
  40.  
  41. void footnote();
  42. void parse();
  43. void refs();
  44. void convert();
  45. void process_line();
  46. int lookup();
  47.  
  48. main(argc,argv)
  49. int argc;
  50. char **argv;
  51. {
  52. FILE * infile;
  53. FILE * outfile;
  54.     if (argc==4 && argv[3][0]=='-' && argv[3][1]=='d')
  55.         debug = TRUE;
  56.  
  57.     if (argc != 3 && !debug) {
  58.         fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  59.         return(1);
  60.     }
  61.     if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  62.         fprintf(stderr,"%s: Can't open %s for reading\n",
  63.             argv[0], argv[1]);
  64.         return(1);
  65.     }
  66.     if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  67.         fprintf(stderr,"%s: Can't open %s for writing\n",
  68.             argv[0], argv[2]);
  69.     }
  70.     parse(infile);
  71.     convert(infile,outfile);
  72.     return(0);
  73. }
  74.  
  75. /* scan the file and build a list of line numbers where particular levels are */
  76. void parse(a)
  77. FILE *a;
  78. {
  79.     static char line[MAX_LINE_LEN];
  80.     char *c;
  81.     int lineno=0;
  82.     int lastline=0;
  83.  
  84.     while (fgets(line,MAX_LINE_LEN,a)) 
  85.     {
  86.     lineno++;
  87.     if (isdigit(line[0]))
  88.     {
  89.         if (list == NULL)    
  90.             head = (list = (struct LIST *) malloc(sizeof(struct LIST)));
  91.         else
  92.             list = (list->next = (struct LIST *) malloc(sizeof(struct LIST)));
  93.         list->line = lastline = lineno;
  94.         list->level = line[0] - '0';
  95.         list->string = (char *) malloc (strlen(line)+1);
  96.         c = strtok(&(line[1]),"\n");
  97.         strcpy(list->string, c);
  98.         list->next = NULL;
  99.     }
  100.     if (line[0]=='?')
  101.     {
  102.         if (keylist == NULL)    
  103.             keyhead = (keylist = (struct LIST *) malloc(sizeof(struct LIST)));
  104.         else
  105.             keylist = (keylist->next = (struct LIST *) malloc(sizeof(struct LIST)));
  106.         keylist->line = lastline;
  107.         keylist->level = line[0] - '0';
  108.         keylist->string = (char *) malloc (strlen(line)+1);
  109.         c = strtok(&(line[1]),"\n");
  110.         strcpy(keylist->string, c);
  111.         keylist->next = NULL;
  112.     }
  113.     }
  114.     rewind(a);
  115.     }
  116.  
  117. /* look up an in text reference */
  118. int
  119. lookup(s)
  120. char *s;
  121. {
  122.     char *c;
  123.     char tokstr[MAX_LINE_LEN];
  124.     char *match; 
  125.     int l;
  126.  
  127.     strcpy(tokstr, s);
  128.  
  129.     /* first try the ? keyword entries */
  130.     keylist = keyhead;
  131.     while (keylist != NULL)
  132.     {
  133.         c = keylist->string;
  134.         while (isspace(*c)) c++;
  135.         if (!strcmp(s, c)) return(keylist->line);
  136.         keylist = keylist->next;
  137.         }
  138.  
  139.     /* then try titles */
  140.     match = strtok(tokstr, " \n\t");
  141.     l = 0; /* level */
  142.     
  143.     list = head;
  144.     while (list != NULL)
  145.     {
  146.         c = list->string;
  147.         while (isspace(*c)) c++;
  148.         if (!strcmp(match, c)) 
  149.         {
  150.             l = list->level;
  151.             match = strtok(NULL, "\n\t ");
  152.             if (match == NULL)
  153.             {
  154.                 return(list->line);
  155.                 }
  156.             }
  157.         if (l > list->level)
  158.             break;
  159.         list = list->next;
  160.         }
  161.     return(-1);
  162.     }
  163.  
  164. /* search through the list to find any references */
  165. void
  166. refs(l, f)
  167. int l;
  168. FILE *f;
  169. {
  170.     int curlevel;
  171.     char str[MAX_LINE_LEN];
  172.     char *c;
  173.  
  174.     /* find current line */
  175.     list = head;
  176.     while (list->line != l)
  177.         list = list->next;
  178.     curlevel = list->level;
  179.     list = list->next;        /* look at next element before going on */
  180.     while (list != NULL)
  181.     {
  182.         /* we are onto the next topic so stop */
  183.         if (list->level == curlevel)
  184.             break;
  185.         /* these are the next topics down the list */
  186.         if (list->level == curlevel+1)
  187.         {
  188.             c = list->string;
  189.             while (isspace(*c)) c++;
  190.             fprintf(f,"\\par{\\uldb %s}",c);
  191.             fprintf(f,"{\\v loc%d}\n",list->line);
  192.             }
  193.         list = list->next;
  194.         }
  195.     }
  196.  
  197. /* generate an RTF footnote with reference char c and text s */
  198. void footnote(c, s, b)
  199. char c;
  200. char *s;
  201. FILE *b;
  202. {
  203.     fprintf(b,"%c{\\footnote %c %s}\n",c,c,s);
  204.     }
  205.  
  206. void
  207. convert(a,b)
  208.     FILE *a,*b;
  209. {
  210.     static char line[MAX_LINE_LEN];
  211.     
  212.     /* generate rtf header */
  213.     fprintf(b,"{\\rtf1\\ansi ");        /* vers 1 rtf, ansi char set */
  214.     fprintf(b,"\\deff0");                /* default font font 0 */
  215.     /* font table: font 0 proportional, font 1 fixed */
  216.     fprintf(b,"{\\fonttbl{\\f0\\fswiss Helv;}{\\f1\\fmodern Courier;}{\\f2\\fmodern Pica;}}\n");
  217.  
  218.     /* process each line of the file */
  219.     while (fgets(line,MAX_LINE_LEN,a)) {
  220.        process_line(line, b);
  221.        }
  222.  
  223.     /* close final page and generate trailer */
  224.     fprintf(b,"}{\\plain \\page}\n");
  225.     fprintf(b,"}\n");
  226. }
  227.  
  228. void
  229. process_line(line, b)
  230.     char *line;
  231.     FILE *b;
  232. {
  233.     static int line_count = 0;
  234.     static char line2[MAX_LINE_LEN];
  235.     static int last_line;
  236.     int i;
  237.     int j;
  238.     static int startpage = 1;
  239.     char str[MAX_LINE_LEN];
  240.     char topic[MAX_LINE_LEN];
  241.     int k, l;
  242.     static int tabl=0;
  243.     static int para=0;
  244.     static int llpara=0;
  245.     static int inquote = FALSE;
  246.     static int inref = FALSE;
  247.  
  248.     line_count++;
  249.  
  250.     i = 0;
  251.     j = 0;
  252.     while (line[i] != '\0')
  253.     {
  254.         switch(line[i])
  255.         {
  256.             case '\\':
  257.             case '{':
  258.             case '}':
  259.                 line2[j] = '\\';
  260.                 j++;
  261.                 line2[j] = line[i];
  262.                 break;
  263.             case '\r':
  264.             case '\n':
  265.                 break;
  266.             case '`':    /* backquotes mean boldface or link */
  267.                 if (line[1]==' ')    /* tabular line */
  268.                     line2[j] = line[i];
  269.                 else if ((!inref) && (!inquote))
  270.                 {
  271.                     k=i+1;    /* index into current string */
  272.                     l=0;    /* index into topic string */
  273.                     while ((line[k] != '`') && (line[k] != '\0'))
  274.                     {
  275.                         topic[l] = line[k];
  276.                         k++;
  277.                         l++;
  278.                         }
  279.                     topic[l] = '\0';
  280.                     k = lookup(topic);
  281.                     if ((k > 0) && (k != last_line))
  282.                     {
  283.                         line2[j++] = '{';
  284.                         line2[j++] = '\\';
  285.                         line2[j++] = 'u';
  286.                         line2[j++] = 'l';
  287.                         line2[j++] = 'd';
  288.                         line2[j++] = 'b';
  289.                         line2[j] = ' ';
  290.                         inref = k;
  291.                         }
  292.                     else
  293.                     {
  294.                         if (debug)
  295.                             fprintf(stderr,"Can't make link for \042%s\042 on line %d\n",topic,line_count);
  296.                         line2[j++] = '{';
  297.                         line2[j++] = '\\';
  298.                         line2[j++] = 'b';
  299.                         line2[j] = ' ';
  300.                         inquote = TRUE;
  301.                         }
  302.                     }
  303.                 else
  304.                 {
  305.                     if (inquote && inref)
  306.                         fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
  307.                     if (inquote)
  308.                     {
  309.                         line2[j] = '}';
  310.                         inquote = FALSE;
  311.                         }
  312.                     if (inref)
  313.                     {
  314.                         /* must be inref */
  315.                         sprintf(topic,"%d",inref);
  316.                         line2[j++] = '}';
  317.                         line2[j++] = '{';
  318.                         line2[j++] = '\\';
  319.                         line2[j++] = 'v';
  320.                         line2[j++] = ' ';
  321.                         line2[j++] = 'l';
  322.                         line2[j++] = 'o';
  323.                         line2[j++] = 'c';
  324.                         k = 0;
  325.                         while (topic[k] != '\0')
  326.                         {
  327.                             line2[j++] = topic[k];
  328.                             k++;
  329.                             }
  330.                         line2[j] = '}';
  331.                         inref = 0;
  332.                         }
  333.                 }
  334.                 break;
  335.             default:
  336.                 line2[j] = line[i];
  337.             }
  338.         i++;
  339.         j++;
  340.         line2[j] = '\0';
  341.         }
  342.  
  343.     i = 1;
  344.  
  345.     switch(line[0]) {        /* control character */
  346.        case '?': {            /* interactive help entry */
  347.         if ((line2[1] != '\0') && (line2[1] != ' '))
  348.             footnote('K',&(line2[1]),b);
  349.           break;
  350.        }
  351.        case '@': {            /* start/end table */
  352.           break;            /* ignore */
  353.        }
  354.        case '#': {            /* latex table entry */
  355.           break;            /* ignore */
  356.        }
  357.        case '%': {            /* troff table entry */
  358.           break;            /* ignore */
  359.        }
  360.        case '\n':            /* empty text line */
  361.             fprintf(b,"\\par\n");
  362.             llpara = para;
  363.             para = 0;
  364.             tabl = 0;
  365.             break;
  366.        case ' ': {            /* normal text line */
  367.           if ((line2[1] == '\0') || (line2[1] == '\n'))
  368.           {
  369.                 fprintf(b,"\\par\n"); 
  370.                 llpara = para;
  371.                 para = 0;
  372.                 tabl = 0;
  373.                 }
  374.           if (line2[1] == ' ') 
  375.           {
  376.                 if (!tabl)
  377.                 {
  378.                     fprintf(b,"\\par\n"); 
  379.                     }
  380.                 fprintf(b,"{\\pard \\plain \\f1\\fs20 ");
  381.                   fprintf(b,"%s",&line2[1]); 
  382.                 fprintf(b,"}\\par\n");
  383.                 llpara = 0;
  384.                 para = 0;
  385.                 tabl = 1